package com.chaoli.reggie_diy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chaoli.reggie_diy.common.CustomException;
import com.chaoli.reggie_diy.common.R;
import com.chaoli.reggie_diy.domain.Dish;
import com.chaoli.reggie_diy.domain.DishFlavor;
import com.chaoli.reggie_diy.domain.Setmeal;
import com.chaoli.reggie_diy.domain.SetmealDish;
import com.chaoli.reggie_diy.dto.DishDto;
import com.chaoli.reggie_diy.mapper.DishMapper;
import com.chaoli.reggie_diy.service.DishFlavorService;
import com.chaoli.reggie_diy.service.DishService;
import com.chaoli.reggie_diy.service.SetmealDishService;
import com.chaoli.reggie_diy.service.SetmealService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomNumberEditor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {

    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private SetmealDishService setmealDishService;

    @Autowired
    private SetmealService setmealService;

    /**
     * 新增菜品，同时保存对应的口味数据
     *
     * @param dishDto
     */
    @Override
    public void saveWithFlavor(DishDto dishDto) {
        //保存菜品的基本信息到dish表
        //mp首先将dish的id生成好了再保存到数据库中
        this.save(dishDto);
        //菜品id
        Long dishId = dishDto.getId();
        //菜品口味
        List<DishFlavor> dishFlavors = dishDto.getFlavors();
        dishFlavors = dishFlavors.stream().map((dishFlavor) -> {
            dishFlavor.setDishId(dishId);
            return dishFlavor;
        }).collect(Collectors.toList());
        //保存菜品口味数据到菜品口味表dish_flavor
        dishFlavorService.saveBatch(dishFlavors);
    }

    //根据菜品id查询菜品信息和口味信息
    @Override
    public DishDto getDishAndFlavorById(Long id) {
        //查询菜品基本信息,从dish表
        Dish dish = this.getById(id);
        DishDto dishDto = new DishDto();
        //将dish的基本信息拷贝到dishDto中
        BeanUtils.copyProperties(dish, dishDto);
        //查询菜品口味信息，从dish_flavor表
        LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DishFlavor::getDishId, id);
        List<DishFlavor> dishFlavorList = dishFlavorService.list(queryWrapper);
        dishDto.setFlavors(dishFlavorList);

        return dishDto;
    }

    //修改菜品，包括口味信息
    @Override
    public void updateWithFlavor(DishDto dishDto) {
        //更新dish表基本数据
        this.updateById(dishDto);
        //删除dish_flavor表的口味数据
//        前端传的 Dish的id 而不是口味的id
//        所以如果用removeById在数据库中是找不到的
        LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DishFlavor::getDishId, dishDto.getId());
        dishFlavorService.remove(queryWrapper);
        //添加修改后的口味数据
        List<DishFlavor> flavors = dishDto.getFlavors();
        List<DishFlavor> flavorList = flavors.stream().map(flavor -> {
            flavor.setDishId(dishDto.getId());
            return flavor;
        }).collect(Collectors.toList());
        dishFlavorService.saveBatch(flavorList);
    }

    /**
     * 菜品单个删除和批量删除
     * <p>
     * 需要检查菜品的status属性是否为0
     *
     * @param ids
     */
    @Override
    public void deleteByIdsWithFalvor(@RequestParam("ids") List<Long> ids) {
        LambdaQueryWrapper<Dish> dishQueryWrapper = new LambdaQueryWrapper<>();
        dishQueryWrapper.in(ids != null, Dish::getId, ids);
        List<Dish> dishList = this.list(dishQueryWrapper);
        for (Dish dish : dishList) {
            if (dish.getStatus() == 1) {
                throw new CustomException("删除的菜品中有正在售卖的菜品，无法删除！!!");
            } else {
                this.removeById(dish);
                //菜品对应的口味也要删除
                LambdaQueryWrapper<DishFlavor> dishFlavorQueryWrapper = new LambdaQueryWrapper<>();
                dishFlavorQueryWrapper.in(DishFlavor::getDishId, ids);
                dishFlavorService.remove(dishFlavorQueryWrapper);
            }
        }
    }

    /**
     * 优化根据ids删除套餐
     * <p>
     * 1.判断要删除的菜品在不在售卖的套餐中，如果在那不能删除
     * 2.要先判断要删除的菜品是否在售卖，如果在售卖也不能删除
     *
     * @param ids
     */
    @Override
    public R<String> deleteByIdsPerfect(List<Long> ids) {
        //如果菜品没有关联套餐，直接删除
        LambdaQueryWrapper<SetmealDish> setmealDishQueryWrapper = new LambdaQueryWrapper<>();
        setmealDishQueryWrapper.in(ids != null, SetmealDish::getDishId, ids);
        List<SetmealDish> setmealDishList = setmealDishService.list(setmealDishQueryWrapper);
        if (setmealDishList.size() == 0) {
            this.deleteByIdsWithFalvor(ids);
            return R.success("菜品删除成功");
        }
        //如果菜品关联套餐，并且该套餐正在售卖，不能删除
        //得到需要删除的菜品所关联的套餐id
        ArrayList<Long> setmealIdList = new ArrayList<>();
        for (SetmealDish setmealDish : setmealDishList) {
            setmealIdList.add(setmealDish.getSetmealId());
        }
        //查询出要删除的菜品所关联的套餐
        LambdaQueryWrapper<Setmeal> setmealQueryWrapper = new LambdaQueryWrapper<>();
        setmealQueryWrapper.in(Setmeal::getId, setmealIdList);
        List<Setmeal> setmealList = setmealService.list(setmealQueryWrapper);
        for (Setmeal setmeal : setmealList) {
            if (setmeal.getStatus() == 1){
                R.error("删除的菜品中有关联在售套餐，无法删除");
            }
        }
        //如果菜品关联套餐，并且没有售卖，可以删除
        this.deleteByIdsWithFalvor(ids);
        return R.success("菜品删除成功！！");
    }
}
